#include "SocketIO.h"
#include <unistd.h>
#include <errno.h>
#include <cstdio>
#include <sys/socket.h>


/**
 * SocketIO类的构造函数
 * @param fd 文件描述符，用于初始化SocketIO对象
 */
SocketIO::SocketIO(int fd)
:_fd(fd)
{

}
SocketIO::~SocketIO()
{
    //TOASK 是否要关闭文件描述符
    close(_fd);
}
int SocketIO::readn(char *buf, int len)
{
    int left=len;
    char *pbuf=buf;
    ssize_t ret;
    while(left>0)
    {
        ret = read(_fd,pbuf,left);
        if (-1==ret&&errno==EINTR)
        {
            continue;
        }
        else if(-1==ret)
        {
            perror("read error");
            return -1;
        }
        else if(0==ret)
        {
            //断开连接
            break;
        }
        else
        {
            left-=ret;
            pbuf+=ret;
        }
    }
    return left;//返回剩余未读的字节数
    

}
int SocketIO::writen(const char *buf, int len)
{
    int left = len;
    const char *pbuf=buf;
    ssize_t ret;
    while (left>0)
    {
        ret = write(_fd,pbuf,left);
        if (-1==ret&&errno==EINTR)
        {
            return left;
        }
        else if(-1==ret)
        {
            perror("write error");
            return -1;
        }
        else if(0==ret)
        {
            break;
        }
        else
        {
            left-=ret;
            pbuf+=ret;
        }
    }
    return left;
    
}
int SocketIO::readLine(char *buf, int len)
{
    int left=len-1;
    int total=0;
    char *pbuf=buf;
    int ret;
    while(left>0)
    {
        //首先先用recv读取部分 看看有没有\n，没有就读去ret，有就读到检索的索引
        ret = recv(_fd,pbuf,left,MSG_PEEK);
        if (-1==ret&&errno==EINTR)
        {
            continue;
        }
        else if(-1==ret)
        {
            perror("readLine error");
            return -1;
        }
        else if(0==ret)
        {
            //断开连接
            break;
        }
        else
        {
            for(int idx=0;idx<ret;idx++)
            {
                //读到\n就返回
                if(pbuf[idx]=='\n')
                {
                    int sz = idx+1;
                    readn(pbuf,sz);
                    pbuf +=sz;
                    *pbuf='\0';
                    return total + sz;
                }
            }
            
            readn(pbuf,ret);
            pbuf+=ret;
            total+=ret;
            left-=ret;
        }
    }
    *pbuf='\0';//如果读取不到\n，则把最后一个字符置为'\0'
    return total;

}